package com.sk.weichat.mvp.presenter;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;

import com.sk.weichat.R;
import com.sk.weichat.bean.Friend;
import com.sk.weichat.bean.message.ChatMessage;
import com.sk.weichat.bean.message.ChatRecord;
import com.sk.weichat.bean.message.XmppMessage;
import com.sk.weichat.db.dao.ChatMessageDao;
import com.sk.weichat.db.dao.FriendDao;
import com.sk.weichat.helper.PrivacySettingHelper;
import com.sk.weichat.mvp.contract.ChatContract;
import com.sk.weichat.ui.base.CoreManager;
import com.sk.weichat.ui.message.ChatActivity;
import com.sk.weichat.util.TimeUtils;
import com.sk.weichat.util.ToastUtil;
import com.sk.weichat.xmpp.listener.ChatMessageListener;
import com.xuan.xuanhttplibrary.okhttp.HttpUtils;
import com.xuan.xuanhttplibrary.okhttp.callback.ListCallback;
import com.xuan.xuanhttplibrary.okhttp.result.ArrayResult;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import okhttp3.Call;

import static com.sk.weichat.xmpp.listener.ChatMessageListener.MESSAGE_SEND_SUCCESS;

public class ChatContentPresenter implements ChatContract.Presenter {

    private final ChatContract.ChatView mChatView;
    private final Context mContext;
    private CoreManager mCoreManager;
    private Friend mFriend;
    private String mLoginUserId;
    private List<ChatMessage> mChatMessages;// 存储聊天消息
    private int mPageSize = 20;
    private boolean mHasMoreData = true;

    public ChatContentPresenter(ChatContract.ChatView chatView, CoreManager coreManager) {
        this.mChatView = chatView;
        mContext = (Context) chatView;
        this.mCoreManager = coreManager;

    }

    public void bandData(Friend friend, String loginUserId, List<ChatMessage> chatMessages) {
        mFriend = friend;
        mLoginUserId = loginUserId;
        mChatMessages = chatMessages;
    }

    public void loadContentData(boolean scrollToBottom, boolean isSearch, double mSearchTime) {

        if (scrollToBottom && mChatMessages.size() == 0) {
            //添加一条系统加密提示
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.setType(XmppMessage.TYPE_SYSTEM_ENTRYPT);
            chatMessage.setFromUserId(mCoreManager.getSelf().getUserId());
            chatMessage.setContent(mContext.getResources().getString(R.string.chat_encrypt_tips));
            chatMessage.setMySend(false);// 表示不是自己发的
            mChatMessages.add(chatMessage);
        }

        long mMinId;
        if (mChatMessages.size() > 1) {
            mMinId = mChatMessages.get(1).getTimeSend();
        } else {

            ChatMessage chat = ChatMessageDao.getInstance().getLastChatMessage(mLoginUserId, mFriend.getUserId());
            if (chat != null && chat.getTimeSend() != 0) {
                mMinId = chat.getTimeSend() + 2;
            } else {
                mMinId = TimeUtils.sk_time_current_time();
            }
        }

        List<ChatMessage> chatLists;
        if (isSearch) {// 查询时就不做分页限制了，因为被查询的消息可能在二十条以外
            chatLists = ChatMessageDao.getInstance().searchMessagesByTime(mLoginUserId,
                    mFriend.getUserId(), mSearchTime);
        } else {
            chatLists = ChatMessageDao.getInstance().getSingleChatMessages(mLoginUserId,
                    mFriend.getUserId(), mMinId, mPageSize);
        }

        if (chatLists == null || chatLists.size() <= 0) {
            if (!scrollToBottom) {// 加载漫游
                getNetSingle();
            }
        } else {

            long currTime = TimeUtils.sk_time_current_time();
            for (int i = 0; i < chatLists.size(); i++) {
                ChatMessage message = chatLists.get(i);
                // 防止过期的消息出现在列表中
                if (message.getDeleteTime() > 0 && message.getDeleteTime() < currTime) {
                    ChatMessageDao.getInstance().deleteSingleChatMessage(mLoginUserId, mFriend.getUserId(), message.getPacketId());
                    continue;
                }
                mChatMessages.add(1, message);
            }

            if (isSearch) {
                isSearch = false;
                int position = 0;
                for (int i = 1; i < mChatMessages.size(); i++) {
                    if (mChatMessages.get(i).getDoubleTimeSend() == mSearchTime) {
                        position = i;
                    }
                }
                mChatView.updateContent(position);// 定位到该条消息
            } else {
                if (scrollToBottom) {
                    mChatView.updateContent(scrollToBottom);
                } else {
                    mChatView.updateContent(chatLists.size());
                }
            }
            mChatView.onHeaderRefreshingCompleted(mHasMoreData);
        }
    }

    public void getNetSingle() {
        Map<String, String> params = new HashMap();
        long endTime;
        if (mChatMessages != null && mChatMessages.size() > 1) {// 本地有数据，截止时间为本地最早的一条消息的timeSend
            endTime = mChatMessages.get(1).getTimeSend() * 1000;
        } else {// 本地无数据，截止时间为当前时间0
            endTime = System.currentTimeMillis();
        }

        long startTime;
        String chatSyncTimeLen = String.valueOf(PrivacySettingHelper.getPrivacySettings(mContext).getChatSyncTimeLen());
        if (Double.parseDouble(chatSyncTimeLen) == -2) {// 不同步
            mChatView.onHeaderRefreshingCompleted(true);
            return;
        }

        if (Double.parseDouble(chatSyncTimeLen) == -1 || Double.parseDouble(chatSyncTimeLen) == 0) {// 同步 永久 startTime == downloadTime
            startTime = 1262275200000l ;
        } else {
            long syncTimeLen = (long) (Double.parseDouble(chatSyncTimeLen) * 24 * 60 * 60 * 1000);// 得到消息同步时长
            startTime = System.currentTimeMillis() - syncTimeLen;
        }

        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("receiver", mFriend.getUserId());
        params.put("startTime", String.valueOf(startTime));// 2010-01-01 00:00:00  服务端返回的数据为倒序返回
        params.put("endTime", String.valueOf(endTime));
        params.put("pageSize", String.valueOf(mPageSize));
        params.put("pageIndex", "0");

        HttpUtils.get().url(mCoreManager.getConfig().GET_CHAT_MSG)
                .params(params)
                .build()
                .execute(new ListCallback<ChatRecord>(ChatRecord.class) {
                    @Override
                    public void onResponse(ArrayResult<ChatRecord> result) {
                        List<ChatRecord> chatRecordList = result.getData();

                        if (chatRecordList != null && chatRecordList.size() > 0) {
                            long currTime = TimeUtils.sk_time_current_time();
                            for (int i = 0; i < chatRecordList.size(); i++) {
                                ChatRecord data = chatRecordList.get(i);
                                String messageBody = data.getBody();
                                messageBody = messageBody.replaceAll("&quot;", "\"");
                                ChatMessage chatMessage = new ChatMessage(messageBody);

                                // 有一种情况，因为服务器1个小时才去删除一次过期消息，所以可能会拉到已过期的时间
                                if (chatMessage.getDeleteTime() > 1 && chatMessage.getDeleteTime() < currTime) {
                                    // 已过期的消息,扔掉
                                    continue;
                                }

                                if (!TextUtils.isEmpty(chatMessage.getFromUserId()) &&
                                        chatMessage.getFromUserId().equals(mLoginUserId)) {
                                    chatMessage.setMySend(true);
                                }

                                chatMessage.setSendRead(true); // 漫游的默认已读
                                // 漫游的默认已上传
                                chatMessage.setUpload(true);
                                chatMessage.setUploadSchedule(100);
                                chatMessage.setMessageState(MESSAGE_SEND_SUCCESS);

                                if (TextUtils.isEmpty(chatMessage.getPacketId())) {
                                    if (!TextUtils.isEmpty(data.getMessageId())) {
                                        chatMessage.setPacketId(data.getMessageId());
                                    } else {
                                        chatMessage.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));
                                    }
                                }

                                if (ChatMessageDao.getInstance().roamingMessageFilter(chatMessage.getType())) {
                                    ChatMessageDao.getInstance().saveRoamingChatMessage(mLoginUserId, mFriend.getUserId(), chatMessage);
                                }
                            }
                            mHasMoreData = chatRecordList.size() == mPageSize;
                            notifyChatAdapter();
                        } else {
                            mHasMoreData = false;
                            mChatView.onHeaderRefreshingCompleted(mHasMoreData);
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {

                    }
                });
    }

    private void notifyChatAdapter() {
        long mMinId;
        if (mChatMessages.size() > 1) {
            mMinId = mChatMessages.get(1).getTimeSend();
        } else {
            ChatMessage chat = ChatMessageDao.getInstance().getLastChatMessage(mLoginUserId, mFriend.getUserId());
            if (chat != null && chat.getTimeSend() != 0) {
                mMinId = chat.getTimeSend() + 2;
            } else {
                mMinId = TimeUtils.sk_time_current_time();
            }
        }
        // 代码等跑到这里来说明 mMinId 一定没有查到数据，同步了漫游之后我们再次使用 mMinId 去查询一下数据
        List<ChatMessage> chatLists = ChatMessageDao.getInstance().getSingleChatMessages(mLoginUserId,
                mFriend.getUserId(), mMinId, mPageSize);
        if (chatLists == null || chatLists.size() == 0) {
            mHasMoreData = false;
            mChatView.onHeaderRefreshingCompleted(mHasMoreData);
            return;
        }

        for (int i = 0; i < chatLists.size(); i++) {
            ChatMessage message = chatLists.get(i);
            mChatMessages.add(1, message);
        }

        mChatView.onHeaderRefreshingCompleted(mHasMoreData);
        mChatView.updateContent(chatLists.size());

    }

    /**
     * 获取漫游消息
     */
    public void synchronizeChatHistory() {
        // 在调用该方法的时候，用户可能还会去下拉获取漫游，导致出现了重复的消息
        // 当该方法在调用时，禁止用户下拉
        mChatView.onHeaderRefreshingCompleted(false);

        long startTime;
        String chatSyncTimeLen = String.valueOf(PrivacySettingHelper.getPrivacySettings(mContext).getChatSyncTimeLen());
        if (Double.parseDouble(chatSyncTimeLen) == -2) {// 不同步
            mChatView.onHeaderRefreshingCompleted(true);
            return;
        }

        long downloadTime = mFriend.getDownloadTime();
        if (Double.parseDouble(chatSyncTimeLen) == -1 || Double.parseDouble(chatSyncTimeLen) == 0) {// 同步 永久 startTime == downloadTime
            startTime = downloadTime > 1262275200000l ? downloadTime : 1262275200000l;
        } else {
            long syncTimeLen = (long) (Double.parseDouble(chatSyncTimeLen) * 24 * 60 * 60 * 1000);// 得到消息同步时长
            startTime = System.currentTimeMillis() - syncTimeLen;
            startTime = downloadTime > startTime ? downloadTime : startTime;
        }

        Map<String, String> params = new HashMap();
        params.put("access_token", mCoreManager.getSelfStatus().accessToken);
        params.put("receiver", mFriend.getUserId());
        params.put("startTime", String.valueOf(startTime));// 2010-01-01 00:00:00  服务端返回的数据为倒序返回
        params.put("endTime", String.valueOf(System.currentTimeMillis()));
        params.put("pageSize", String.valueOf(1000));// 尽量传一个大的值 一次性拉下来
        // params.put("pageIndex", "0");

        HttpUtils.get().url(mCoreManager.getConfig().GET_CHAT_MSG)
                .params(params)
                .build()
                .execute(new ListCallback<ChatRecord>(ChatRecord.class) {
                    @Override
                    public void onResponse(ArrayResult<ChatRecord> result) {
                        final List<ChatRecord> chatRecordList = result.getData();
                        if (chatRecordList != null && chatRecordList.size() > 0) {
                            new Thread(() -> {
                                ArrayList<ChatMessage> chatMessages = new ArrayList<>();
                                long currTime = TimeUtils.sk_time_current_time();

                                for (int i = 0; i < chatRecordList.size(); i++) {
                                    ChatRecord data = chatRecordList.get(i);
                                    String messageBody = data.getBody();
                                    messageBody = messageBody.replaceAll("&quot;", "\"");
                                    ChatMessage chatMessage = new ChatMessage(messageBody);

                                    // 有一种情况，因为服务器1个小时才去删除一次过期消息，所以可能会拉到已过期的时间
                                    if (chatMessage.getDeleteTime() > 1 && chatMessage.getDeleteTime() < currTime) {
                                        // 已过期的消息,扔掉
                                        continue;
                                    }

                                    if (!TextUtils.isEmpty(chatMessage.getFromUserId()) &&
                                            chatMessage.getFromUserId().equals(mLoginUserId)) {
                                        chatMessage.setMySend(true);
                                    }

                                    chatMessage.setSendRead(true); // 漫游的默认已读
                                    // 漫游的默认已上传
                                    chatMessage.setUpload(true);
                                    chatMessage.setUploadSchedule(100);
                                    chatMessage.setMessageState(MESSAGE_SEND_SUCCESS);

                                    if (TextUtils.isEmpty(chatMessage.getPacketId())) {
                                        if (!TextUtils.isEmpty(data.getMessageId())) {
                                            chatMessage.setPacketId(data.getMessageId());
                                        } else {
                                            chatMessage.setPacketId(UUID.randomUUID().toString().replaceAll("-", ""));
                                        }
                                    }

                                    if (ChatMessageDao.getInstance().roamingMessageFilter(chatMessage.getType())) {
                                        ChatMessageDao.getInstance().decryptDES(chatMessage);
                                        ChatMessageDao.getInstance().handlerRoamingSpecialMessage(chatMessage);
                                        if (ChatMessageDao.getInstance().saveNewSingleChatMessage(mLoginUserId, mFriend.getUserId(), chatMessage)) {
                                            chatMessages.add(chatMessage);
                                        }
                                    }
                                }

                                if (chatMessages.size() != 0) {
                                    ((Activity) mContext).runOnUiThread(new Runnable() {

                                        @Override
                                        public void run() {
                                            for (int i = chatMessages.size() - 1; i >= 0; i--) {
                                                mChatMessages.add(chatMessages.get(i));
                                            }
                                            // 有可能本地已经发送或接收到了消息，需要对mChatMessages重新排序
                                            Comparator<ChatMessage> comparator = (c1, c2) -> (int) (c1.getDoubleTimeSend() - c2.getDoubleTimeSend());
                                            Collections.sort(mChatMessages, comparator);
                                            mChatView.updateContent(true);
                                            mChatView.onHeaderRefreshingCompleted(true);
                                        }
                                    });
                                } else {
                                    mChatView.onHeaderRefreshingCompleted(true);
                                }

                                FriendDao.getInstance().updateDownloadTime(mFriend.getUserId(), System.currentTimeMillis());

                            }).start();
                        }
                    }

                    @Override
                    public void onError(Call call, Exception e) {
                        mChatView.onHeaderRefreshingCompleted(true);
                        ToastUtil.showErrorData(mContext);
                    }
                });
    }


}
